package com.netflix.governator.guice.actions;
import java.lang.annotation.Annotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Binding;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Scope;
import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.spi.DefaultBindingScopingVisitor;
import com.google.inject.spi.DefaultBindingTargetVisitor;
import com.google.inject.spi.DefaultElementVisitor;
import com.google.inject.spi.LinkedKeyBinding;
import com.netflix.governator.guice.PostInjectorAction;
/**
* Explicit singleton bindings are not eagerly created when running in Stage.DEVELOPMENT.
* This method iterates through all explicit bindings (those made though a guice module) for singletons
* and creates them eagerly after the injector was created.
*/
public class CreateAllBoundSingletons implements PostInjectorAction {
@Override
public void call(Injector injector) {
for (final Binding<?> binding : injector.getBindings().values()) {
binding.acceptVisitor(new DefaultElementVisitor<Void>() {
public <T> Void visit(final Binding<T> binding) {
// This takes care of bindings to concrete classes
binding.acceptScopingVisitor(new DefaultBindingScopingVisitor<Void>() {
@Override
public Void visitScope(Scope scope) {
if (scope.equals(Scopes.SINGLETON)) {
binding.getProvider().get();
}
return null;
}
});
// This takes care of the interface .to() bindings
binding.acceptTargetVisitor(new DefaultBindingTargetVisitor<T, Void>() {
public Void visit(LinkedKeyBinding<? extends T> linkedKeyBinding) {
Key<?> key = linkedKeyBinding.getLinkedKey();
Class<?> type = key.getTypeLiteral().getRawType();
if (type.getAnnotation(Singleton.class) != null ||
type.getAnnotation(javax.inject.Singleton.class) != null) {
binding.getProvider().get();
}
return null;
}
});
return visitOther(binding);
}
});
}
}
}